<!-- HTML header for doxygen 1.8.13-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.13"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>MTB CAT1 Peripheral driver library: USBFS        (USB Full-Speed Device)</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="navtreedata.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<script type="text/javascript">
  $(document).ready(initResizable);
</script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen_style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr style="height: 56px;">
  <td id="projectlogo"><a href="http://www.cypress.com/"><img alt="Logo" src="IFXCYP_one-line.png"/></a></td>
  <td id="projectalign" style="padding-left: 0.5em;">
   <div id="projectname">MTB CAT1 Peripheral driver library</div>
  </td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.13 -->
<script type="text/javascript">
var searchBox = new SearchBox("searchBox", "search",false,'Search');
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
$(function() {
  initMenu('',true,false,'search.php','Search');
  $(document).ready(function() { init_search(); });
});
</script>
<div id="main-nav"></div>
</div><!-- top -->
<div id="side-nav" class="ui-resizable side-nav-resizable">
  <div id="nav-tree">
    <div id="nav-tree-contents">
      <div id="nav-sync" class="sync"></div>
    </div>
  </div>
  <div id="splitbar" style="-moz-user-select:none;" 
       class="ui-resizable-handle">
  </div>
</div>
<script type="text/javascript">
$(document).ready(function(){initNavTree('group__group__usbfs__dev__drv.html','');});
</script>
<div id="doc-content">
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0" 
        name="MSearchResults" id="MSearchResults">
</iframe>
</div>

<div class="header">
  <div class="summary">
<a href="#groups">API Reference</a>  </div>
  <div class="headertitle">
<div class="title">USBFS (USB Full-Speed Device)</div>  </div>
</div><!--header-->
<div class="contents">
<a name="details" id="details"></a><h2 class="groupheader">General Description</h2>
<p>The USBFS driver provides an API to interact with a fixed-function USB block. </p>
<p>The functions and other declarations used in this driver are in cy_usbfs_dev_drv.h. You can include cy_pdl.h to get access to all functions and declarations in the PDL.</p>
<p>The USB block supports Host and Device modes of operation. This version of the driver supports only Device mode.</p>
<p><b>Features:</b></p><ul>
<li>Complies with USB Specification 2.0</li>
<li>Supports full-speed peripheral device operation with a signaling bit rate of 12 Mbps.</li>
<li>Supports eight data endpoints and one control endpoint.</li>
<li>Provides a shared 512-byte buffer for data endpoints.</li>
<li>Provides dedicated 8-byte memory for control endpoint (EP0).</li>
<li>Supports four types of transfers: bulk, interrupt, isochronous, and control</li>
<li>Supports bus- and self-powered configurations</li>
<li>Supports USB suspend, resume, and remove wakeup.</li>
<li>Supports three types of logical transfer modes:<ul>
<li>CPU (No DMA) mode (Mode 1).</li>
<li>Manual DMA mode (Mode 2).</li>
<li>Automatic DMA mode (Mode 3).</li>
</ul>
</li>
<li>Supports the maximum packet size:<ul>
<li>512 bytes using Mode 1 and Mode 2.</li>
<li>1023 bytes for isochronous transfer using Mode 3.</li>
</ul>
</li>
<li>Provides integrated 22 Ohm USB termination resistors on D+ and D- lines, and 1.5 kOhm pull-up resistor on the D+ line.</li>
<li>Supports USB 2.0 Link Power Management (LPM).</li>
</ul>
<h1><a class="anchor" id="group_usbfs_dev_drv_use_cases"></a>
Common Use Cases</h1>
<p><b>The primary usage model for the USBFS driver is to provide a defined API interface to <a href="https://Infineon.github.io/usbdev/usbfs_dev_api_reference_manual/html/index.html" target="_blank">USB Device Middleware</a> component that works on top of it.</b> <br />
The driver also provides an API interface for the application to implement the required functionality:</p><ul>
<li><a class="el" href="group__group__usbfs__dev__drv.html#group_usbfs_dev_drv_callbacks">Callbacks Usage</a></li>
<li><a class="el" href="group__group__usbfs__dev__drv.html#group_usbfs_dev_drv_low_power">Low Power Support</a></li>
<li><a class="el" href="group__group__usbfs__dev__drv.html#group_usbfs_dev_drv_lpm">Link Power Management (LPM)</a></li>
<li><a class="el" href="group__group__usbfs__dev__drv.html#group_usbfs_dev_drv_vbus">VBUS Detection</a></li>
</ul>
<h1><a class="anchor" id="group_usbfs_dev_drv_configuration"></a>
Configuration Considerations</h1>
<p>This section explains how to configure the USBFS driver and system resources to enable USB Device operation. The pointers to the populated <a class="el" href="structcy__stc__usbfs__dev__drv__config__t.html">cy_stc_usbfs_dev_drv_config_t</a> configuration structure and allocated context are passed in the middleware initialization. function Cy_USB_Dev_Init. After middleware initialization, it calls <a class="el" href="group__group__usbfs__dev__hal__functions__common.html#gadd8371859c363f83d16376550f19d90f">Cy_USBFS_Dev_Drv_Init</a> to initialize the USBFS driver for Device operation.</p>
<h2><a class="anchor" id="group_usbfs_dev_drv_config"></a>
Configure Driver</h2>
<p>To configure the USBFS driver in Device mode, the configuration structure <a class="el" href="structcy__stc__usbfs__dev__drv__config__t.html">cy_stc_usbfs_dev_drv_config_t</a> parameters must be populated. The configuration structure content significantly depends on the selected endpoints management mode parameter:</p>
<ul>
<li><p class="startli"><a class="el" href="group__group__usbfs__dev__drv__enums.html#ggaaf6cf71cc366279eb82aefed4f81e2d1ac3176862482a8aa82d109a1886568007">CY_USBFS_DEV_DRV_EP_MANAGEMENT_CPU</a> <br />
 The <em>epAccess, intrLevelSel and enableLpm</em> must be provided. All other parameters are do not cares for this mode. Refer to section <a class="el" href="group__group__usbfs__dev__drv.html#group_usbfs_dev_drv_intr">Configure Interrupts</a> to get information about <em>intrLevelSel</em> configuration.</p>
<div class="fragment"><div class="line"><span class="comment">/* Endpoint Buffer Management mode is Manual CPU (Mode 1) */</span></div><div class="line"><span class="keyword">const</span> <a class="code" href="structcy__stc__usbfs__dev__drv__config__t.html">cy_stc_usbfs_dev_drv_config_t</a> USBD_config = </div><div class="line">{</div><div class="line">    <span class="comment">/* Required configuration parameters */</span></div><div class="line">    .<a class="code" href="structcy__stc__usbfs__dev__drv__config__t.html#a9e42980b89acb13104b9ff1ba5044a5f">mode</a>         = <a class="code" href="group__group__usbfs__dev__drv__enums.html#ggaaf6cf71cc366279eb82aefed4f81e2d1ac3176862482a8aa82d109a1886568007">CY_USBFS_DEV_DRV_EP_MANAGEMENT_CPU</a>,</div><div class="line">    .epAccess     = <a class="code" href="group__group__usbfs__dev__drv__enums.html#gga332943f4c8b1dd76803ac661a276d0b5a3c00c5ead5a8a4b84f587c5b48e02c4c">CY_USBFS_DEV_DRV_USE_8_BITS_DR</a>,</div><div class="line">    .intrLevelSel = USBD_INTR_LVL_SEL,</div><div class="line">    .enableLpm    = <span class="keyword">false</span>,</div><div class="line">    </div><div class="line">    <span class="comment">/* Parameters below do not care for this configuration */</span></div><div class="line">    .dmaConfig[0] = NULL,</div><div class="line">    .dmaConfig[1] = NULL,</div><div class="line">    .dmaConfig[2] = NULL,</div><div class="line">    .dmaConfig[3] = NULL,</div><div class="line">    .dmaConfig[4] = NULL,</div><div class="line">    .dmaConfig[5] = NULL,</div><div class="line">    .dmaConfig[6] = NULL,</div><div class="line">    .dmaConfig[7] = NULL,</div><div class="line">    </div><div class="line">    .epBuffer     = NULL,</div><div class="line">    .epBufferSize = 0U,    </div><div class="line">};</div></div><!-- fragment --></li>
<li><p class="startli"><a class="el" href="group__group__usbfs__dev__drv__enums.html#ggaaf6cf71cc366279eb82aefed4f81e2d1a930a0581a66afb3a298b2d6d5b470e1a">CY_USBFS_DEV_DRV_EP_MANAGEMENT_DMA</a> <br />
 To enable DMA operation, the DMA channels must be assigned for each endpoint to be used. Each DMA channel needs a single DMA descriptor to operate. The USBFS driver defines the DMA configuration structure <a class="el" href="structcy__stc__usbfs__dev__drv__dma__config__t.html">cy_stc_usbfs_dev_drv_dma_config_t</a> to be populated for each DMA channel. The code example below provides an initialized USBFS driver DMA configuration structure:</p>
<div class="fragment"><div class="line"><span class="comment">/* Allocate DMA descriptor */</span></div><div class="line"><span class="keyword">static</span> <a class="code" href="structcy__stc__dma__descriptor__t.html">cy_stc_dma_descriptor_t</a> USBD_ep1DmaDescr0;</div><div class="line"></div><div class="line"><span class="comment">/* USBFS DMA configuration structure */</span></div><div class="line"><span class="keyword">static</span> <span class="keyword">const</span> <a class="code" href="structcy__stc__usbfs__dev__drv__dma__config__t.html">cy_stc_usbfs_dev_drv_dma_config_t</a> USBD_ep1DmaConfig0 = </div><div class="line">{</div><div class="line">    <span class="comment">/* DMA channel configuration */</span></div><div class="line">    .<a class="code" href="structcy__stc__usbfs__dev__drv__dma__config__t.html#a8f4ec9857bf5868ec58ce1383b140b5d">base</a>       = DW0,</div><div class="line">    .chNum       = 0U,</div><div class="line">    .priority    = 3U,</div><div class="line">    .preemptable = <span class="keyword">false</span>,</div><div class="line"></div><div class="line">    <span class="comment">/* Allocated descriptor for DMA operation */</span></div><div class="line">    .descr0 = &amp;USBD_ep1DmaDescr0,</div><div class="line"></div><div class="line">    <span class="comment">/* Parameters below do not care for this configuration */</span></div><div class="line">    .descr1 = NULL,</div><div class="line">    .outTrigMux = 0U,</div><div class="line">};</div></div><!-- fragment --><p> The pointers to the DMA configuration structure are required into the <a class="el" href="structcy__stc__usbfs__dev__drv__config__t.html">cy_stc_usbfs_dev_drv_config_t</a> USBFS driver configuration structure to allow the USBFS driver to use DMA channels for used endpoints. The <em>dmaConfig[0]</em> field expects a pointer to the DMA configuration for data endpoint 1, the <em>dmaConfig[1]</em> field pointer to the DMA configuration for data endpoint 2, and so on up to data endpoint 8. The code example below provides an initialized USBFS driver configuration structure which uses endpoint 1:</p>
<div class="fragment"><div class="line"><span class="comment">/* Endpoint Buffer Management mode is Manual DMA (Mode 2) */</span></div><div class="line"><span class="keyword">const</span> <a class="code" href="structcy__stc__usbfs__dev__drv__config__t.html">cy_stc_usbfs_dev_drv_config_t</a> USBD_configDma = </div><div class="line">{</div><div class="line">    <span class="comment">/* Required configuration parameters */</span></div><div class="line">    .<a class="code" href="structcy__stc__usbfs__dev__drv__config__t.html#a9e42980b89acb13104b9ff1ba5044a5f">mode</a>         = <a class="code" href="group__group__usbfs__dev__drv__enums.html#ggaaf6cf71cc366279eb82aefed4f81e2d1a930a0581a66afb3a298b2d6d5b470e1a">CY_USBFS_DEV_DRV_EP_MANAGEMENT_DMA</a>,</div><div class="line">    .epAccess     = <a class="code" href="group__group__usbfs__dev__drv__enums.html#gga332943f4c8b1dd76803ac661a276d0b5a3c00c5ead5a8a4b84f587c5b48e02c4c">CY_USBFS_DEV_DRV_USE_8_BITS_DR</a>,</div><div class="line">    .intrLevelSel = USBD_INTR_LVL_SEL,</div><div class="line">    .enableLpm    = <span class="keyword">false</span>,</div><div class="line">   </div><div class="line">    .dmaConfig[0] = &amp;USBD_ep1DmaConfig0,</div><div class="line">    .dmaConfig[1] = NULL,</div><div class="line">    .dmaConfig[2] = NULL,</div><div class="line">    .dmaConfig[3] = NULL,</div><div class="line">    .dmaConfig[4] = NULL,</div><div class="line">    .dmaConfig[5] = NULL,</div><div class="line">    .dmaConfig[6] = NULL,</div><div class="line">    .dmaConfig[7] = NULL,</div><div class="line">   </div><div class="line">    <span class="comment">/* Parameters below do not care for this configuration */</span></div><div class="line">    .epBuffer     = NULL,</div><div class="line">    .epBufferSize = 0U,</div><div class="line">};</div></div><!-- fragment --></li>
<li><p class="startli"><a class="el" href="group__group__usbfs__dev__drv__enums.html#ggaaf6cf71cc366279eb82aefed4f81e2d1aad338d6b20d33a6cff7f47e2b883ddec">CY_USBFS_DEV_DRV_EP_MANAGEMENT_DMA_AUTO</a> <br />
 DMA Automatic mode needs a DMA channels configuration similar to the described above. But it also requires one more DMA descriptor for each DMA channel and DMA output trigger multiplexer. Refer to the <a class="el" href="group__group__usbfs__dev__drv.html#group_usbfs_dev_drv_dma">Assign and Route DMA Channels</a> section, for more detail about the trigger multiplexer . The code example below provides an initialized USBFS driver DMA configuration structure:</p>
<div class="fragment"><div class="line"><span class="comment">/* Allocate DMA descriptors for DMA operation */</span></div><div class="line"><span class="keyword">static</span> <a class="code" href="structcy__stc__dma__descriptor__t.html">cy_stc_dma_descriptor_t</a> USBD_ep1DmaDescr0;</div><div class="line"><span class="keyword">static</span> <a class="code" href="structcy__stc__dma__descriptor__t.html">cy_stc_dma_descriptor_t</a> USBD_ep1DmaDescr1;</div><div class="line"></div><div class="line"><span class="comment">/* Populate DMA configuration structure for endpoint 1 */</span></div><div class="line"><span class="keyword">static</span> <span class="keyword">const</span> <a class="code" href="structcy__stc__usbfs__dev__drv__dma__config__t.html">cy_stc_usbfs_dev_drv_dma_config_t</a> USBD_ep1DmaConfig1 = </div><div class="line">{</div><div class="line">    <span class="comment">/* DMA channel configuration */</span>        </div><div class="line">    .<a class="code" href="structcy__stc__usbfs__dev__drv__dma__config__t.html#a8f4ec9857bf5868ec58ce1383b140b5d">base</a>        = DW0,</div><div class="line">    .chNum       = 0U,</div><div class="line">    .priority    = 3U,</div><div class="line">    .preemptable = <span class="keyword">false</span>,</div><div class="line">    </div><div class="line">    <span class="comment">/* Allocated descriptors for DMA operation */</span></div><div class="line">    .descr0 = &amp;USBD_ep1DmaDescr0,</div><div class="line">    .descr1 = &amp;USBD_ep1DmaDescr1,</div><div class="line">    </div><div class="line">    <span class="comment">/* DMA routing information: output trigger mux */</span></div><div class="line">    .outTrigMux = USBD_dma_burstend_0_TRIGGER_OUT,</div><div class="line">};</div></div><!-- fragment --><p> The driver requires a buffer for data endpoints to operate. This buffer must be allocated by the user. The buffer size is equal to the sum of all used endpoints maximum packet sizes. If an endpoint belongs to more than one alternate setting, select the greatest maximum packet size for this endpoint. The driver configuration structure <a class="el" href="structcy__stc__usbfs__dev__drv__config__t.html">cy_stc_usbfs_dev_drv_config_t</a> parameters <em>epBuffer and epBufferSize</em> pass the buffer to the driver.</p>
<p class="startli">The code example below provides an initialized USBFS driver configuration structure that uses data endpoint 1 with a maximum packet size of 63 bytes and set 16-bit access:</p>
<div class="fragment"><div class="line"><span class="comment">/* Allocate  buffer for data endpoint for 16-bit access.</span></div><div class="line"><span class="comment">* The buffer size = 63 (maxPacket) + 1 = 64.</span></div><div class="line"><span class="comment">*/</span></div><div class="line"><a class="code" href="group__group__usbfs__dev__drv__macros.html#gaef72dcffc85aefe650f79dd21dbdb29c">CY_USBFS_DEV_DRV_ALLOC_ENDPOINT_BUFFER</a>(USBD_endpointsBuffer, 63 + 1);</div><div class="line"></div><div class="line"><span class="comment">/* Endpoint Buffer Management mode is Automatic DMA (Mode 3) */</span></div><div class="line"><span class="keyword">const</span> <a class="code" href="structcy__stc__usbfs__dev__drv__config__t.html">cy_stc_usbfs_dev_drv_config_t</a> USBD_configDmaAuto = </div><div class="line">{</div><div class="line">    <span class="comment">/* Required configuration parameters */</span></div><div class="line">    .<a class="code" href="structcy__stc__usbfs__dev__drv__config__t.html#a9e42980b89acb13104b9ff1ba5044a5f">mode</a>         = <a class="code" href="group__group__usbfs__dev__drv__enums.html#ggaaf6cf71cc366279eb82aefed4f81e2d1a930a0581a66afb3a298b2d6d5b470e1a">CY_USBFS_DEV_DRV_EP_MANAGEMENT_DMA</a>,</div><div class="line">    .epAccess     = <a class="code" href="group__group__usbfs__dev__drv__enums.html#gga332943f4c8b1dd76803ac661a276d0b5a887ba4b3b96b50ca452a88575b24f7e2">CY_USBFS_DEV_DRV_USE_16_BITS_DR</a>,</div><div class="line">    .intrLevelSel = USBD_INTR_LVL_SEL,</div><div class="line">    .enableLpm    = <span class="keyword">false</span>,</div><div class="line"></div><div class="line">    .dmaConfig[0] = &amp;USBD_ep1DmaConfig1,</div><div class="line">    .dmaConfig[1] = NULL,</div><div class="line">    .dmaConfig[2] = NULL,</div><div class="line">    .dmaConfig[3] = NULL,</div><div class="line">    .dmaConfig[4] = NULL,</div><div class="line">    .dmaConfig[5] = NULL,</div><div class="line">    .dmaConfig[6] = NULL,</div><div class="line">    .dmaConfig[7] = NULL,</div><div class="line"></div><div class="line">    .epBuffer     = USBD_endpointsBuffer,</div><div class="line">    .epBufferSize = 64U,</div><div class="line">};</div></div><!-- fragment --></li>
</ul>
<dl class="section note"><dt>Note</dt><dd>The endpoint buffer allocation depends on the access type used: 8-bit or 16-bit. Refer to <a class="el" href="group__group__usbfs__dev__drv.html#group_usbfs_dev_drv_ep_management_buf_access">Hardware Buffer Access</a> for more information.</dd></dl>
<h2><a class="anchor" id="group_usbfs_dev_drv_pins"></a>
Assign and Configure Pins</h2>
<p>Only dedicated USB pins can be used for USB operation. Keep the default USB pins configuration because after the USBFS driver initializes, the USB block takes control over the pins and drives them properly.</p>
<h2><a class="anchor" id="group_usbfs_dev_drv_clock"></a>
Assign and Configure Clocks</h2>
<p>The USB hardware block requires two clock sources for operation:</p><ul>
<li>Clk_HF3 (USB clock) must be 48 MHz. The accuracy of the USB clock must be within -/+ 0.25%. Note that Clk_HF3 has an integer divider so the input clock can be a multiple of 48. The valid options to get an internal USB clock are PLL or ECO.<br />
 <b>The typical configuration is:</b> the IMO output is used by the PLL to generate Clk_HF3 (USB clock). To meet USB clock accuracy requirements the IMO must be trimmed with USB SOF signal. Therefore, the driver <a class="el" href="group__group__usbfs__dev__hal__functions__common.html#gadd8371859c363f83d16376550f19d90f">Cy_USBFS_Dev_Drv_Init</a> function enables the IMO trim from USB.</li>
<li>Divided Clk_Peri clock (PCLK_USB_CLOCK_DEV_BRS) equal to 100 kHz used to detect a Bus Reset event. Use one of the 8-bit or 16-bit dividers to provide required clock frequency.</li>
</ul>
<p>The code example below shows the connection source path 1 (which expected provide 48 MHz -/+ 0.25% clock) to Clk_HF3 and Bus Reset clock (Clk_Peri assumed to be 50 MHz):</p>
<div class="fragment"><div class="line">    <span class="comment">/* Configure USB Device dedicated clock Clk_HF3 to take source from Path 1 </span></div><div class="line"><span class="comment">    * (without division) and enable it. The Path 1 clock must meet USB Device clock </span></div><div class="line"><span class="comment">    * requirements 48MHz -/+ 0.25%.</span></div><div class="line"><span class="comment">    */</span></div><div class="line">    <a class="code" href="group__group__sysclk__clk__hf__funcs.html#ga2d39c7e5111f9ba0738f032a98b4593e">Cy_SysClk_ClkHfSetSource</a> (3u, <a class="code" href="group__group__sysclk__clk__hf__enums.html#ggabac2d6b9124a00860dcd781a922788d6a69197ee41c916c6e61d81dbe9be1825f">CY_SYSCLK_CLKHF_IN_CLKPATH1</a>);</div><div class="line">    <a class="code" href="group__group__sysclk__clk__hf__funcs.html#ga66c6e94768403ab318f2aa321b4c1e50">Cy_SysClk_ClkHfSetDivider</a>(3u, <a class="code" href="group__group__sysclk__clk__hf__enums.html#ggadfbf0caf87af7cd757648124fb17d1d4a996f9d53d3d78eda51e71dd65b1990c0">CY_SYSCLK_CLKHF_NO_DIVIDE</a>);</div><div class="line">    <a class="code" href="group__group__sysclk__clk__hf__funcs.html#gaf3041fc8333478cc7c8d869d2a535d71">Cy_SysClk_ClkHfEnable</a>(3u);</div><div class="line"></div><div class="line">    <span class="comment">/* Assign divider type and number for USBFS Device Bus Reset Clock */</span></div><div class="line"><span class="preprocessor">    #define USBFS_DEV_BRCLK_DIV_TYPE    (CY_SYSCLK_DIV_16_BIT)</span></div><div class="line"><span class="preprocessor">    #define USBFS_DEV_DIV_NUM           (0U)</span></div><div class="line"></div><div class="line">    <span class="comment">/* Connect assigned divider to be a clock source for USBFS Device Bus Reset Clock */</span></div><div class="line">    <a class="code" href="group__group__sysclk__clk__peripheral__funcs.html#ga2f480c53ecec720ceed823b2692f1698">Cy_SysClk_PeriphAssignDivider</a>(PCLK_USB_CLOCK_DEV_BRS, USBFS_DEV_BRCLK_DIV_TYPE, USBFS_DEV_DIV_NUM);</div><div class="line"></div><div class="line">    <span class="comment">/* Configure USBFS Device Bus Reset Clock to be 100 kHz = 50MHz (Clk_Peri) / 500 and enable it */</span></div><div class="line">    <a class="code" href="group__group__sysclk__clk__peripheral__funcs.html#gae7042898b1b6835673182e462be6976e">Cy_SysClk_PeriphSetDivider</a>   (USBFS_DEV_BRCLK_DIV_TYPE, USBFS_DEV_DIV_NUM, 499u);</div><div class="line">    <a class="code" href="group__group__sysclk__clk__peripheral__funcs.html#ga0725e2b222edc601b7d3f56d86d4ff75">Cy_SysClk_PeriphEnableDivider</a>(USBFS_DEV_BRCLK_DIV_TYPE, USBFS_DEV_DIV_NUM);</div></div><!-- fragment --><p> Refer to <a class="el" href="group__group__sysclk.html">SysClk (System Clock)</a> driver API for more detail about clock configuration.</p>
<p>The FLL (Clock Path 0) with ECO also can be used as an alternative USB source with the next configuration settings, for 48 MHz: </p><div class="fragment"><div class="line"><span class="comment">/*  Fll input 24 MHz +- 0.01% (ECO), output 48 MHz +- 0.1725% */</span></div><div class="line"><a class="code" href="structcy__stc__fll__manual__config__t.html">cy_stc_fll_manual_config_t</a> fllConfig48MHz = </div><div class="line">{</div><div class="line">    .<a class="code" href="structcy__stc__fll__manual__config__t.html#a93a7114899568aa34c09a288957086fc">fllMult</a> = 1820U,</div><div class="line">    .refDiv = 455U,</div><div class="line">    .ccoRange = <a class="code" href="group__group__sysclk__fll__enums.html#ggac8760ee841ca24255c9a4fee494b79aaa8b869d6fc9950701b3664b5c6337dd1b">CY_SYSCLK_FLL_CCO_RANGE2</a>,</div><div class="line">    .enableOutputDiv = <span class="keyword">true</span>,</div><div class="line">    .lockTolerance = 1U,</div><div class="line">    .igain = 7U,</div><div class="line">    .pgain = 2U,</div><div class="line">    .settlingCount = 24U,</div><div class="line">    .outputMode = <a class="code" href="group__group__sysclk__fll__enums.html#gga777e08424e26c9cd8c2602b2114e716baf9198d7cbbee5db8e8c48375125aee74">CY_SYSCLK_FLLPLL_OUTPUT_OUTPUT</a>,</div><div class="line">    .cco_Freq = 194U,</div><div class="line">};</div></div><!-- fragment --><p>And for 96 MHz: </p><div class="fragment"><div class="line"><span class="comment">/*  Fll input 24 MHz +- 0.01% (ECO), output 96 MHz +- 0.1835% */</span></div><div class="line"><a class="code" href="structcy__stc__fll__manual__config__t.html">cy_stc_fll_manual_config_t</a> fllConfig96MHz = </div><div class="line">{</div><div class="line">    .<a class="code" href="structcy__stc__fll__manual__config__t.html#a93a7114899568aa34c09a288957086fc">fllMult</a> = 1712U,</div><div class="line">    .refDiv = 214U,</div><div class="line">    .ccoRange = <a class="code" href="group__group__sysclk__fll__enums.html#ggac8760ee841ca24255c9a4fee494b79aaa6c50c6395080bcf0cc45094a6eaf22b4">CY_SYSCLK_FLL_CCO_RANGE4</a>,</div><div class="line">    .enableOutputDiv = <span class="keyword">true</span>,</div><div class="line">    .lockTolerance = 1U,</div><div class="line">    .igain = 7U,</div><div class="line">    .pgain = 4U,</div><div class="line">    .settlingCount = 24U,</div><div class="line">    .outputMode = <a class="code" href="group__group__sysclk__fll__enums.html#gga777e08424e26c9cd8c2602b2114e716baf9198d7cbbee5db8e8c48375125aee74">CY_SYSCLK_FLLPLL_OUTPUT_OUTPUT</a>,</div><div class="line">    .cco_Freq = 362U,</div><div class="line">};</div></div><!-- fragment --><p>Use these structures with <a class="el" href="group__group__sysclk__fll__funcs.html#ga0e2e272b670cc52ab984291afae6a1fa">Cy_SysClk_FllManualConfigure</a></p>
<h2><a class="anchor" id="group_usbfs_dev_drv_dma"></a>
Assign and Route DMA Channels</h2>
<p>The USBFS driver requires a DMA controller to operate in DMA Manual and Automatic modes. The USB hardware block supports the DMA request and feedback lines for each data endpoint. Therefore, up to eight DMA channels serve eight data endpoints. The connection between the USB block and the DMA channels is set using the trigger muxes infrastructure. The USB block output DMA request line is connected to the DMA channel trigger input. This allows the USB block to request a DMA transfer. The DMA completion output is connected to the USB block burst end input. This allows the USB block to get notification that a DMA transfer has been completed and a next DMA request can be sent. The USBFS driver DMA configuration structure requires the <em>outTrigMux</em> field to provide the trigger mux that performs DMA completion and USB block burst end connection.</p>
<p>Refer to <a class="el" href="group__group__trigmux.html">TrigMux (Trigger Multiplexer)</a> for more detail on the routing capabilities.</p>
<p>The code examples below shows a connection DMA channel and USB block and the define for <em>outTrigMux</em> field initialization for the CY8C6xx6 or CY8C6xx7 devices.</p>
<div class="fragment"><div class="line"><span class="comment">/* Trigger mux that performs DMA completion and USB block burst end connection */</span></div><div class="line"><span class="preprocessor">#define USBD_dma_burstend_0_TRIGGER_OUT TRIG9_OUT_USB_DMA_BURSTEND0</span></div><div class="line"></div><div class="line"><span class="comment">/* USB Block and DMA channel connection */</span></div><div class="line"><a class="code" href="group__group__trigmux__functions.html#ga3671fac144b75c3b3eddc5ab46ae96f6">Cy_TrigMux_Connect</a>(TRIG0_IN_TR_GROUP13_OUTPUT1, TRIG0_OUT_CPUSS_DW0_TR_IN0, <span class="keyword">false</span>, TRIGGER_TYPE_LEVEL);</div><div class="line"><a class="code" href="group__group__trigmux__functions.html#ga3671fac144b75c3b3eddc5ab46ae96f6">Cy_TrigMux_Connect</a>(TRIG9_IN_CPUSS_DW0_TR_OUT0, TRIG9_OUT_USB_DMA_BURSTEND0, <span class="keyword">false</span>, TRIGGER_TYPE_EDGE);</div><div class="line"><a class="code" href="group__group__trigmux__functions.html#ga3671fac144b75c3b3eddc5ab46ae96f6">Cy_TrigMux_Connect</a>(TRIG13_IN_USB_DMA_REQ0, TRIG13_OUT_TR_GROUP0_INPUT28, <span class="keyword">false</span>, TRIGGER_TYPE_LEVEL);</div></div><!-- fragment --><h2><a class="anchor" id="group_usbfs_dev_drv_intr"></a>
Configure Interrupts</h2>
<p><b>The interrupts are mandatory for the USBFS driver operation.</b> The USBFS block provides multiple interrupt sources to be assigned to trigger one of the three interrupts: Low, Medium, or High. This allows to assign different priority to the interrupt sources handling. The <a class="el" href="structcy__stc__usbfs__dev__drv__config__t.html">cy_stc_usbfs_dev_drv_config_t</a> structure provides the <em>intrLevelSel</em> field which initializes the INTR_LVL_SEL register. This register configures which interrupt the interrupt source will trigger.</p>
<dl class="section note"><dt>Note</dt><dd>The interrupt name (Low, Medium, or High) does not specify the interrupt priority. The interrupt priority is configured in NVIC.</dd></dl>
<p>The recommended/default configuration is:</p><ul>
<li>Interrupt Low: Bus Reset, Control Endpoint and SOF.</li>
<li>Interrupt Medium: Endpoint 1-8 Completion.</li>
<li>Interrupt High: Arbiter and LPM.</li>
</ul>
<p>However, the final configuration must be defined by the application.</p>
<div class="fragment"><div class="line"><span class="comment">/* Interrupt Level Select register initialization */</span></div><div class="line"><span class="preprocessor">#define USBD_INTR_LVL_SEL \</span></div><div class="line"><span class="preprocessor">            (CY_USBFS_DEV_DRV_SET_SOF_LVL      (CY_USBFS_DEV_DRV_LVL_LOW) | \</span></div><div class="line"><span class="preprocessor">             CY_USBFS_DEV_DRV_SET_BUS_RESET_LVL(CY_USBFS_DEV_DRV_LVL_LOW) | \</span></div><div class="line"><span class="preprocessor">             CY_USBFS_DEV_DRV_SET_EP0_LVL      (CY_USBFS_DEV_DRV_LVL_LOW) | \</span></div><div class="line"><span class="preprocessor">             CY_USBFS_DEV_DRV_SET_LPM_LVL   (CY_USBFS_DEV_DRV_LVL_HIGH)   | \</span></div><div class="line"><span class="preprocessor">             CY_USBFS_DEV_DRV_SET_ARB_EP_LVL(CY_USBFS_DEV_DRV_LVL_HIGH)   | \</span></div><div class="line"><span class="preprocessor">             CY_USBFS_DEV_DRV_SET_EP1_LVL(CY_USBFS_DEV_DRV_LVL_MEDIUM)    | \</span></div><div class="line"><span class="preprocessor">             CY_USBFS_DEV_DRV_SET_EP2_LVL(CY_USBFS_DEV_DRV_LVL_MEDIUM)    | \</span></div><div class="line"><span class="preprocessor">             CY_USBFS_DEV_DRV_SET_EP3_LVL(CY_USBFS_DEV_DRV_LVL_MEDIUM)    | \</span></div><div class="line"><span class="preprocessor">             CY_USBFS_DEV_DRV_SET_EP4_LVL(CY_USBFS_DEV_DRV_LVL_MEDIUM)    | \</span></div><div class="line"><span class="preprocessor">             CY_USBFS_DEV_DRV_SET_EP5_LVL(CY_USBFS_DEV_DRV_LVL_MEDIUM)    | \</span></div><div class="line"><span class="preprocessor">             CY_USBFS_DEV_DRV_SET_EP6_LVL(CY_USBFS_DEV_DRV_LVL_MEDIUM)    | \</span></div><div class="line"><span class="preprocessor">             CY_USBFS_DEV_DRV_SET_EP7_LVL(CY_USBFS_DEV_DRV_LVL_MEDIUM)    | \</span></div><div class="line"><span class="preprocessor">             CY_USBFS_DEV_DRV_SET_EP8_LVL(CY_USBFS_DEV_DRV_LVL_MEDIUM))</span></div></div><!-- fragment --><p> The <a class="el" href="group__group__usbfs__dev__drv__functions__interrupts.html#ga19b86416f176a19377937c598f413000">Cy_USBFS_Dev_Drv_Interrupt</a> function must be called in the interrupt handler for the selected USB block instance. Note that the <a class="el" href="group__group__usbfs__dev__drv__functions__interrupts.html#ga19b86416f176a19377937c598f413000">Cy_USBFS_Dev_Drv_Interrupt</a> has the parameter <em>intrCause</em> that must be assigned by calling the appropriate interrupt cause function:</p><ul>
<li><a class="el" href="group__group__usbfs__dev__drv__functions__interrupts.html#gab3bad7b7e1dde7206fc6c19383420b38">Cy_USBFS_Dev_Drv_GetInterruptCauseHi</a></li>
<li><a class="el" href="group__group__usbfs__dev__drv__functions__interrupts.html#ga33bcd2fa964a934ca62e6a89e5bfc1bc">Cy_USBFS_Dev_Drv_GetInterruptCauseMed</a></li>
<li><a class="el" href="group__group__usbfs__dev__drv__functions__interrupts.html#ga46f82da15e28a6b289ffed61fe1d9f7c">Cy_USBFS_Dev_Drv_GetInterruptCauseLo</a></li>
</ul>
<div class="fragment"><div class="line"><span class="comment">/*******************************************************************************</span></div><div class="line"><span class="comment">* Function Name: USBD_IsrHigh</span></div><div class="line"><span class="comment">****************************************************************************/</span></div><div class="line"><span class="keyword">static</span> <span class="keywordtype">void</span> USBD_IsrHigh(<span class="keywordtype">void</span>)</div><div class="line">{</div><div class="line">    <span class="comment">/* Call interrupt processing */</span></div><div class="line">    <a class="code" href="group__group__usbfs__dev__drv__functions__interrupts.html#ga19b86416f176a19377937c598f413000">Cy_USBFS_Dev_Drv_Interrupt</a>(USBFS0, <a class="code" href="group__group__usbfs__dev__drv__functions__interrupts.html#gab3bad7b7e1dde7206fc6c19383420b38">Cy_USBFS_Dev_Drv_GetInterruptCauseHi</a>(USBFS0), &amp;usbDrvContext);</div><div class="line">}</div><div class="line"></div><div class="line"></div><div class="line"><span class="comment">/*******************************************************************************</span></div><div class="line"><span class="comment">* Function Name: USBD_IsrMedium</span></div><div class="line"><span class="comment">****************************************************************************/</span></div><div class="line"><span class="keyword">static</span> <span class="keywordtype">void</span> USBD_IsrMedium(<span class="keywordtype">void</span>)</div><div class="line">{</div><div class="line">    <span class="comment">/* Call interrupt processing */</span></div><div class="line">    <a class="code" href="group__group__usbfs__dev__drv__functions__interrupts.html#ga19b86416f176a19377937c598f413000">Cy_USBFS_Dev_Drv_Interrupt</a>(USBFS0, <a class="code" href="group__group__usbfs__dev__drv__functions__interrupts.html#ga33bcd2fa964a934ca62e6a89e5bfc1bc">Cy_USBFS_Dev_Drv_GetInterruptCauseMed</a>(USBFS0), &amp;usbDrvContext);</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">/*******************************************************************************</span></div><div class="line"><span class="comment">* Function Name: USBD_IsrLow</span></div><div class="line"><span class="comment">****************************************************************************/</span></div><div class="line"><span class="keyword">static</span> <span class="keywordtype">void</span> USBD_IsrLow(<span class="keywordtype">void</span>)</div><div class="line">{</div><div class="line">    <span class="comment">/* Call interrupt processing */</span></div><div class="line">    <a class="code" href="group__group__usbfs__dev__drv__functions__interrupts.html#ga19b86416f176a19377937c598f413000">Cy_USBFS_Dev_Drv_Interrupt</a>(USBFS0, <a class="code" href="group__group__usbfs__dev__drv__functions__interrupts.html#ga46f82da15e28a6b289ffed61fe1d9f7c">Cy_USBFS_Dev_Drv_GetInterruptCauseLo</a>(USBFS0), &amp;usbDrvContext);</div><div class="line">}</div></div><!-- fragment --><p> Finally, the interrupts must be configured and interrupt handler routines hook up to NVIC. The code below assigns the interrupt priorities accordingly to interrupt names. The priorities among the USBFS interrupts are as follows: High - the greatest; Medium - the middle; Low - the lowest.</p>
<dl class="section note"><dt>Note</dt><dd>For proper operation in Manual DMA mode (Mode 2) the Arbiter interrupt source must be assigned to interrupt which priority is greater than interrupt triggered by Data Endpoint 1-8 Completion interrupt sources. <br />
For Automatic DMA mode (Mode 3) the rule above is recommend to follow.</dd></dl>
<div class="fragment"><div class="line"><span class="comment">/* Assign USBFS Device interrupt number and priority */</span></div><div class="line"><span class="keyword">const</span> <a class="code" href="structcy__stc__sysint__t.html">cy_stc_sysint_t</a> USBD_IntrHighConfig =</div><div class="line">{</div><div class="line">    .<a class="code" href="structcy__stc__sysint__t.html#a204a8f07adf056c8d3dd818136da853f">intrSrc</a> = (<a class="code" href="group__group__sysint__enums.html#ga7e1129cd8a196f4284d41db3e82ad5c8">IRQn_Type</a>) usb_interrupt_hi_IRQn,</div><div class="line">    .intrPriority = 5U,</div><div class="line">};</div><div class="line"><span class="keyword">const</span> <a class="code" href="structcy__stc__sysint__t.html">cy_stc_sysint_t</a> USBD_IntrMediumConfig =</div><div class="line">{</div><div class="line">    .<a class="code" href="structcy__stc__sysint__t.html#a204a8f07adf056c8d3dd818136da853f">intrSrc</a> = (<a class="code" href="group__group__sysint__enums.html#ga7e1129cd8a196f4284d41db3e82ad5c8">IRQn_Type</a>) usb_interrupt_med_IRQn,</div><div class="line">    .intrPriority = 6U,</div><div class="line">};</div><div class="line"><span class="keyword">const</span> <a class="code" href="structcy__stc__sysint__t.html">cy_stc_sysint_t</a> USBD_IntrLowConfig =</div><div class="line">{</div><div class="line">    .<a class="code" href="structcy__stc__sysint__t.html#a204a8f07adf056c8d3dd818136da853f">intrSrc</a> = (<a class="code" href="group__group__sysint__enums.html#ga7e1129cd8a196f4284d41db3e82ad5c8">IRQn_Type</a>) usb_interrupt_lo_IRQn,</div><div class="line">    .intrPriority = 7U,</div><div class="line">};</div></div><!-- fragment --><div class="fragment"><div class="line"><span class="comment">/* Hook interrupt service routines */</span></div><div class="line">(void) <a class="code" href="group__group__sysint__functions.html#gab2ff6820a898e9af3f780000054eea5d">Cy_SysInt_Init</a>(&amp;USBD_IntrLowConfig,    &amp;USBD_IsrLow);</div><div class="line">(void) <a class="code" href="group__group__sysint__functions.html#gab2ff6820a898e9af3f780000054eea5d">Cy_SysInt_Init</a>(&amp;USBD_IntrMediumConfig, &amp;USBD_IsrMedium);</div><div class="line">(void) <a class="code" href="group__group__sysint__functions.html#gab2ff6820a898e9af3f780000054eea5d">Cy_SysInt_Init</a>(&amp;USBD_IntrHighConfig,   &amp;USBD_IsrHigh);</div></div><!-- fragment --><h1><a class="anchor" id="group_usbfs_dev_drv_ep_management"></a>
Endpoint Buffer Management Modes</h1>
<p>The USBFS hardware block supports three endpoint buffer management modes: CPU (No DMA) mode (Mode 1), Manual DMA mode (Mode 2), and Automatic DMA mode (Mode 3). These modes are listed using enum <a class="el" href="group__group__usbfs__dev__drv__enums.html#gaaf6cf71cc366279eb82aefed4f81e2d1">cy_en_usbfs_dev_drv_ep_management_mode_t</a>. The following sub-sections provide more information about the endpoint buffer management.</p>
<h2><a class="anchor" id="group_usbfs_dev_drv_ep_management_buff"></a>
Hardware buffers</h2>
<p>The USBFS block has a 512-byte hardware buffer that is divided between all data endpoints used in the selected configuration. How the hardware buffer is divided between endpoints depends on the selected endpoint buffer management modes:</p>
<ul>
<li><a class="el" href="group__group__usbfs__dev__drv.html#group_usbfs_dev_drv_ep_management_mode1">CPU mode (Mode 1)</a> and <a class="el" href="group__group__usbfs__dev__drv.html#group_usbfs_dev_drv_ep_management_mode2">Manual DMA mode (Mode 2)</a> Each data endpoint consumes space (number of bytes) in the hardware buffer that is equal to the endpoint maximum packet size defined in the endpoint descriptor. The total space consumed by all endpoints is restricted by the size of hardware buffer (512 bytes). When an endpoint appears in the different alternate settings and has a different maximum packet size, the greatest value is selected to the allocate space of the endpoint in the hardware buffer. This is to ensure correct USB Device operation when interface alternate settings are changed. Note that endpoint can consume extra byte in the hardware buffer when 16-bit access is used (See <a class="el" href="group__group__usbfs__dev__drv.html#group_usbfs_dev_drv_ep_management_buf_access">Hardware Buffer Access</a> for more information).</li>
<li><a class="el" href="group__group__usbfs__dev__drv.html#group_usbfs_dev_drv_ep_management_mode3">Automatic DMA mode (Mode 3)</a> Each data endpoint consumes 32 bytes in the hardware buffer (if all eight endpoints are used, the consumed buffer space is 32 * 8 = 256 byte). This buffer is called "dedicated endpoint buffer". It acts as an endpoint FIFO. The remaining space (256 bytes, if all eight endpoints are used) in the hardware buffer is used by any endpoint that currently communicates. This part of the buffer is called "common area". This hardware buffer configuration gives a sufficient dedicated buffer size for each used endpoint and common area for operation. The total space consumed by all endpoints is not restricted by the size of the hardware buffer.</li>
</ul>
<p>To access the hardware buffer, the endpoint data register is read or written by CPU or DMA. On each read or write, buffer pointers are updated to access a next data element.</p>
<h2><a class="anchor" id="group_usbfs_dev_drv_ep_management_buf_access"></a>
Hardware Buffer Access</h2>
<p>The USBFS block provides two sets of data registers: 8-bit and 16-bit. Either the 8-bit endpoint data register or the 16-bit endpoint data register can be used to read/write to the endpoint buffer. The buffer access is controlled by the <em>epAccess</em> field of the driver configuration structure <a class="el" href="structcy__stc__usbfs__dev__drv__config__t.html">cy_stc_usbfs_dev_drv_config_t</a>. The endpoint hardware buffer and SRAM buffer must be allocated using the rules below when the 16-bit access is used:</p><ul>
<li>The buffer size must be even. If the endpoint maximum packet size is odd the allocated buffer size must be equal to (maximum packet size + 1).</li>
<li>The buffer must be aligned to the 2-byte boundary.</li>
</ul>
<p>The driver provides the <a class="el" href="group__group__usbfs__dev__drv__macros.html#gaef72dcffc85aefe650f79dd21dbdb29c">CY_USBFS_DEV_DRV_ALLOC_ENDPOINT_BUFFER</a> macro that applies the rules above to allocate the SRAM buffer for an endpoint. This macro should be used by application to hide configuration differences. <b>However, in this case the application must ignore extra bytes in the buffer.</b> Alternately, apply the rules above only for the 16-bits access type configuration.</p>
<p>The driver firmware allocates an endpoint hardware buffer (dividing hardware buffer between utilized endpoints). Therefore, for <a class="el" href="group__group__usbfs__dev__drv.html#group_usbfs_dev_drv_ep_management_mode1">CPU mode (Mode 1)</a> and <a class="el" href="group__group__usbfs__dev__drv.html#group_usbfs_dev_drv_ep_management_mode2">Manual DMA mode (Mode 2)</a>, an endpoint whose maximum packet size is odd, consumes an extra byte in the hardware buffer when the 16-bit access is used. This is not applicable for <a class="el" href="group__group__usbfs__dev__drv.html#group_usbfs_dev_drv_ep_management_mode3">Automatic DMA mode (Mode 3)</a> because endpoints dedicated buffer are even and aligned.</p>
<p>In addition, to operate in <a class="el" href="group__group__usbfs__dev__drv.html#group_usbfs_dev_drv_ep_management_mode3">Automatic DMA mode (Mode 3)</a>, the driver needs an internal SRAM buffer for endpoints. The buffer size is a sum of all endpoint buffers. When the 16-bit access is used, each endpoint buffer must be allocated using the rules above. The driver configuration structure <a class="el" href="structcy__stc__usbfs__dev__drv__config__t.html">cy_stc_usbfs_dev_drv_config_t</a> has <em>epBuffer and epBufferSize</em> fields to pass the allocated buffer to the driver. <br />
For example: the USB Device uses three data endpoints whose max packets are 63 bytes, 63 bytes, and 8 bytes. The endpoints buffer for the driver must be allocated as follows:</p><ul>
<li>8-bits: uint8_t endpointsBuffer[63 + 63 + 8];</li>
<li>16-bits: uint8_t endpointsBuffer[(63+1) + (63+1) + 8] CY_ALLIGN(2); or CY_USBFS_DEV_DRV_ALLOC_ENDPOINT_BUFFER((63+1) + (63+1) + 8);</li>
</ul>
<h2><a class="anchor" id="group_usbfs_dev_drv_ep_management_mode1"></a>
CPU mode (Mode 1)</h2>
<p>CPU handles data transfers between the user-provided SRAM endpoint-buffer and the USB block hardware-buffer when <a class="el" href="group__group__usbfs__dev__hal__functions__data__xfer.html#ga3699408b8336670b36c2e7a3fa6949d7">Cy_USBFS_Dev_Drv_ReadOutEndpoint</a> or <a class="el" href="group__group__usbfs__dev__hal__functions__data__xfer.html#ga65db7019eafec3e38e8fbca316f92673">Cy_USBFS_Dev_Drv_LoadInEndpoint</a> is called.</p>
<div class="image">
<img src="usbfs_ep_mngmnt_mode1.png" alt="usbfs_ep_mngmnt_mode1.png"/>
</div>
<h2><a class="anchor" id="group_usbfs_dev_drv_ep_management_mode2"></a>
Manual DMA mode (Mode 2)</h2>
<p>DMA handles data transfers between the user-provided SRAM endpoint buffer and the USB block hardware buffer. The DMA request is issued by CPU to execute a data transfer when <a class="el" href="group__group__usbfs__dev__hal__functions__data__xfer.html#ga3699408b8336670b36c2e7a3fa6949d7">Cy_USBFS_Dev_Drv_ReadOutEndpoint</a> or <a class="el" href="group__group__usbfs__dev__hal__functions__data__xfer.html#ga65db7019eafec3e38e8fbca316f92673">Cy_USBFS_Dev_Drv_LoadInEndpoint</a>.</p>
<div class="image">
<img src="usbfs_ep_mngmnt_mode2.png" alt="usbfs_ep_mngmnt_mode2.png"/>
</div>
<h2><a class="anchor" id="group_usbfs_dev_drv_ep_management_mode3"></a>
Automatic DMA mode (Mode 3)</h2>
<p>DMA handles data transfers between the driver SRAM endpoints buffer and the USB block hardware buffer. The USB block generates DMA requests automatically. When USB transfer starts, the USB block triggers DMA requests to transfer data between the driver endpoint buffer and the hardware buffer until transfer completion. The common area acts as a FIFO to (and keeps data that does not fit into) the endpoint dedicated buffer. For IN endpoints, the dedicated buffer is pre-loaded before enabling USB Host access to the endpoint. This gives time for the DMA to provide remaining data before underflow occurs. The USB block hardware has a feedback connection with the DMA and does not issue new DMA request until it receives notification that the previous DMA transfer completed. When the <a class="el" href="group__group__usbfs__dev__hal__functions__data__xfer.html#ga3699408b8336670b36c2e7a3fa6949d7">Cy_USBFS_Dev_Drv_ReadOutEndpoint</a> or <a class="el" href="group__group__usbfs__dev__hal__functions__data__xfer.html#ga65db7019eafec3e38e8fbca316f92673">Cy_USBFS_Dev_Drv_LoadInEndpoint</a> function is called, the memcpy function is used to copy data from/into the driver endpoints buffer to the user-provided endpoint buffer. The driver provides the <a class="el" href="group__group__usbfs__dev__hal__functions__endpoint__config.html#ga73f805a814fa4a1c66dc4224d2002319">Cy_USBFS_Dev_Drv_OverwriteMemcpy</a> function to replace memcpy function by one that has been custom implemented (the DMA can be used for data copy).</p>
<div class="image">
<img src="usbfs_ep_mngmnt_mode3.png" alt="usbfs_ep_mngmnt_mode3.png"/>
</div>
<dl class="section warning"><dt>Warning</dt><dd>When DMA data transfer is not fast enough, an overflow or underflow interrupt triggers for the impacted endpoint. This must never happen because this error condition indicates a system failure with no recovery. To fix this, get the DMA channel assigned to this endpoint greater priority or increase the clock the DMA operates at.</dd></dl>
<h1><a class="anchor" id="group_usbfs_dev_drv_callbacks"></a>
Callbacks Usage</h1>
<p>The driver provides the following callbacks that can be used by the application:</p><ol type="1">
<li>Data endpoint 1-8 completion. This callback is invoked when the USB Host completed communication with the endpoint. For IN endpoints, it means that data has been read by the USB Host. For OUT endpoints, it means that data has been written by the USB Host. Call <a class="el" href="group__group__usbfs__dev__drv__functions__interrupts.html#ga639d1ef6c6898e0c0c01321ba286e38d">Cy_USBFS_Dev_Drv_RegisterEndpointCallback</a> to register callback function.</li>
<li>Start Of Frame packet received. This can be used in the application to synchronize with SOF packets or for monitoring the bus activity. Call <a class="el" href="group__group__usbfs__dev__drv__functions__interrupts.html#ga0aa6031c260bbbc2ca75c8f4a9795c06">Cy_USBFS_Dev_Drv_RegisterSofCallback</a> to register callback function.</li>
<li>LPM (Link Power Management) packet received. This must be used to implement LPM power optimization. Call <a class="el" href="group__group__usbfs__dev__drv__functions__interrupts.html#ga8750c5860193d62e7946792467615f4a">Cy_USBFS_Dev_Drv_RegisterLpmCallback</a> to register callback function.</li>
</ol>
<p>Also, the driver provides callbacks for a Bus Reset event and Control Endpoint 0 communication events (setup packet, in packet, out packet). But these callbacks are used by middleware and must not be used by the application directly. The middleware provides appropriate hooks for these events.</p>
<h1><a class="anchor" id="group_usbfs_dev_drv_vbus"></a>
VBUS Detection</h1>
<p>The USB specification requires that no device supplies current on VBUS at its upstream facing port at any time. To meet this requirement, the device must monitors for the presence or absence of VBUS and removes power from the Dp/Dm pull-up resistor if VBUS is absent. The USBFS driver does not provide any support of VBUS monitoring or detection. The application firmware must implement the required functionality using a VDDUSB power pad or GPIO. Refer to the Universal Serial Bus (USB) Device Mode section, sub-section VBUS Detection in the technical reference manual (TRM).</p>
<p>Connect the VBUS through a resistive network when the regular GPIO is used for VBUS detection to save the pin from voltage picks on VBUS, or use GPIO tolerant over the voltage. An example schematic is shown below.</p>
<div class="image">
<img src="usbfs_vbus_connect_schem.png" alt="usbfs_vbus_connect_schem.png"/>
</div>
<dl class="section note"><dt>Note</dt><dd>Power is removed when the USB cable is removed from the USB Host for bus-powered USB Device. Therefore, such a USB Device complies with specification requirement above.</dd></dl>
<h1><a class="anchor" id="group_usbfs_dev_drv_low_power"></a>
Low Power Support</h1>
<p>The USBFS driver supports the USB Suspend, Resume, and Remote Wakeup functionality. This functionality is tightly related with the user application. The USBFS driver provides only the API interface which helps the user achieve the desired low-power behavior. The additional processing is required from the user application. The description of application processing is provided below.</p>
<p>Normally, the USB Host sends an SOF packet every 1 ms (at full speed), and this keeps the USB Device awake. The USB Host suspends the USB Device by not sending anything to the USB Device for 3 ms. To recognize this condition, the bus activity must be checked. This can be done using the <a class="el" href="group__group__usbfs__dev__drv__functions__low__power.html#gabd7fa97f9881ff3992851fecb9fa6ca2">Cy_USBFS_Dev_Drv_CheckActivity</a> function or by monitoring the SOF interrupt. A suspended device may draw no more than 0.5 mA from VBUS. Therefore, put the device into low-power mode to consume less current. The <a class="el" href="group__group__usbfs__dev__drv__functions__low__power.html#ga1e254e18f758dbc14cb74b6ef93fc705">Cy_USBFS_Dev_Drv_Suspend</a> function must be called before entering low-power mode. When the USB Host wants to wake the device after a suspend, it does so by reversing the polarity of the signal on the data lines for at least 20 ms. The resume signaling is completed with a low-speed end-of-packet signal. The USB block is disabled during Deep Sleep or Hibernate low-power modes. To exit a low-power mode when USB Host drives resume, a falling edge interrupt on Dp must be configured before entering these modes. The <a class="el" href="group__group__usbfs__dev__drv__functions__low__power.html#ga4f96e219508bc0ea6d645d79ebb75c34">Cy_USBFS_Dev_Drv_Resume</a> function must be called after exiting the low-power mode. To resume communication with the USB Host, the data endpoints must be managed: the OUT endpoints must be enabled and IN endpoints must be loaded with data.</p>
<dl class="section note"><dt>Note</dt><dd>After entering low-power mode, the data which was left in the IN or OUT endpoint buffers is not restored after the device's wake-up and is lost. Therefore, it must be stored in the SRAM for OUT endpoint or read by the Host for the IN endpoint before entering Low-power mode.</dd></dl>
<p>If the USB Device supports remote wakeup functionality, the application has to use middleware function Cy_USB_Dev_IsRemoteWakeupEnabled to determine whether remote wakeup was enabled by the USB Host. When the device is suspended and it determines the conditions to initiate a remote wakeup are met, the application must call the <a class="el" href="group__group__usbfs__dev__drv__functions__low__power.html#gaeb6514f79104fe1ad21cd68a155808b5">Cy_USBFS_Dev_Drv_Force</a> function to force the appropriate J and K states onto the USB bus, signaling a remote wakeup condition. Note that <a class="el" href="group__group__usbfs__dev__drv__functions__low__power.html#ga4f96e219508bc0ea6d645d79ebb75c34">Cy_USBFS_Dev_Drv_Resume</a> must be called first to restore the condition.</p>
<h1><a class="anchor" id="group_usbfs_dev_drv_lpm"></a>
Link Power Management (LPM)</h1>
<p>Link Power Management is a USB low-power mode feature that provides more flexibility in terms of features than the existing resume mode. This feature is similar to the existing Suspend/Resume, but has transitional latencies of tens of microseconds between power states (instead of 3 to greater than 20 millisecond latencies of the USB 2.0 Suspend/Resume).</p>
<p>USB2.0 Power states are re-arranged as below with the introduction of LPM. The existing power states are re-named with LPM:</p><ul>
<li>L0 (On)</li>
<li>L1 (Sleep) &ndash; Newly Introduced State in LPM</li>
<li>L2 (Suspend)</li>
<li>L3 (Powered-Off)</li>
</ul>
<p>LPM state transitions between is shown below:</p>
<div class="image">
<img src="usbfs_lpm_state_transition.png" alt="usbfs_lpm_state_transition.png"/>
</div>
<p>For example, a USB Host must transition a link from L1 (Sleep) to L0 before transitioning it to L2 (Suspend), and similarly when transitioning from L2 to L1.</p>
<p>When a USB Host is ready to transition a USB Device from L0 to a deeper power savings state, it issues an LPM transaction to the USB Device. The USB Device function responds with an ACK if it is ready to make the transition or a NYET (Not Yet) if it is not ready (usually because it is has data pending for the USB Host). A USB Device will transmit a STALL handshake if it does not support the requested link state. If the USB Device detects errors in either of the token packets or does not understand the protocol extension transaction, no handshake is returned.</p>
<div class="image">
<img src="usbfs_lpm_responses.png" alt="usbfs_lpm_responses.png"/>
</div>
<p>After USB Device is initialized, the LPM transaction is to be acknowledged (ACKed) meaning that the device is ready to enter the requested low-power mode. To override this behavior, use <a class="el" href="group__group__usbfs__dev__drv__functions__lpm.html#ga1e0ca4d1b2ba8009065362cfeec5f078">Cy_USBFS_Dev_Drv_Lpm_SetResponse</a>. <br />
 The USB block provides an interrupt source to define that an LPM transaction was received and acknowledged (ACKed). Use the <a class="el" href="group__group__usbfs__dev__drv__functions__interrupts.html#ga8750c5860193d62e7946792467615f4a">Cy_USBFS_Dev_Drv_RegisterLpmCallback</a> function to register the application level callback function to serve the LPM transaction. The callback function can notify the application about an LPM transaction and can use <a class="el" href="group__group__usbfs__dev__drv__functions__lpm.html#ga5290ed3e38780181cd2b931b9d39ea99">Cy_USBFS_Dev_Drv_Lpm_GetBeslValue</a> read to read Best Effort Service Latency (BESL) values provided as part of an LPM transaction. The BESL value indicates the amount of time from the start of a resume to when the USB Host attempts to begin issuing transactions to the USB Device. The application must use the value BESL to decide which low-power mode is entered to meet wakeup timing. The LPM transaction also contains the field that allows a remote to wake up. Use <a class="el" href="group__group__usbfs__dev__drv__functions__lpm.html#ga33b0d0c7b758c9a0d9c499d13cd900f8">Cy_USBFS_Dev_Drv_Lpm_RemoteWakeUpAllowed</a> to get its value.</p>
<p>LPM related USB 2.0 Extension Descriptor provides attributes fields named baseline BESL and deep BESL to provide a range of values for different low-power optimization. The recommended use of these fields is that the baseline BESL field will have a value less than the deep BESL field. The expected use is the baseline BESL value communicates a nominal power savings design point and the deep BESL value communicates a significant power saving design point. For example, when the received BESL is less than baseline BESL, leave the device in Active mode. When it is between baseline BESL and deep BESL, put the device into Deep Sleep mode. When it is greater than deep BESL, put the device into Hibernate mode.</p>
<dl class="section note"><dt>Note</dt><dd>The driver implements the USB Full-Speed device which does not support the LPM NYET response.</dd>
<dd>
The device will restart after Hibernate mode and the USB Device must be initialized at the application level. Call the initialization functions instead of <a class="el" href="group__group__usbfs__dev__drv__functions__low__power.html#ga4f96e219508bc0ea6d645d79ebb75c34">Cy_USBFS_Dev_Drv_Resume</a>. The application must ensure that the device will resume within the time defined in the BESL value of LPM request.</dd></dl>
<h1><a class="anchor" id="group_usbfs_drv_more_information"></a>
More Information</h1>
<p>For more detail on the USB Full-Speed Device peripheral, refer to the section Universal Serial Bus (USB) Device Mode in the technical reference manual (TRM).</p>
<h1><a class="anchor" id="group_usbfs_drv_changelog"></a>
Changelog</h1>
<table class="doxtable">
<tr>
<th>Version</th><th>Changes</th><th>Reason for Change </th></tr>
<tr>
<td>2.30 </td><td><a class="el" href="group__group__usbfs__dev__hal__functions__common.html#gafc1931448521bc57d22c602e451d978a">Cy_USBFS_Dev_Drv_DeInit()</a> was updated to reduce power consumption of the USB IP block after deinitialization.  </td><td><a class="el" href="group__group__usbfs__dev__hal__functions__common.html#gafc1931448521bc57d22c602e451d978a">Cy_USBFS_Dev_Drv_DeInit()</a> did not return all registers to the default value, which caused the USB IP block to consume more current when it was disabled.   </td></tr>
<tr>
<td>2.20.3 </td><td>Minor syntax update and spell fix. </td><td>Updated for compliance with MISRA-C:2012 standard and fixing spell errors.  </td></tr>
<tr>
<td>2.20.2 </td><td>Minor syntax updates. Added specific deviations documentation. </td><td>Updated for compliance with MISRA-C:2012 standard.  </td></tr>
<tr>
<td>2.20.1 </td><td>Minor documentation updates. </td><td>Documentation enhancement.  </td></tr>
<tr>
<td rowspan="2">2.20 </td><td>Fix configuration register value restoring in resume routine after Deep Sleep.  </td><td>Fix issue that USB Device stops working in DMA modes after wake up from Deep Sleep.   </td></tr>
<tr>
<td>The LPM requests are ignored after wake up from Deep Sleep and the host starts sending SOFs. </td><td>Updated <a class="el" href="group__group__usbfs__dev__drv__functions__low__power.html#ga4f96e219508bc0ea6d645d79ebb75c34">Cy_USBFS_Dev_Drv_Resume</a> function to restore LPM control register after exit Deep Sleep.   </td></tr>
<tr>
<td>2.10 </td><td>Returns the data toggle bit into the previous state after detecting that the host is retrying an OUT transaction. </td><td>The device was not able to recover the data toggle bit and continues communication through the endpoint after the host retried the OUT transaction (the retried transaction has the same toggle bit as the previous had).   </td></tr>
<tr>
<td>2.0 </td><td>The list of changes to support the MBED-OS USB Device stack is provided below:<ul>
<li>Changed the processing of the control transfers.</li>
<li>Updated the endpoint 0 service functions to update the endpoint 0 registers before the function returns.</li>
<li>Moved the set-device-address processing into the driver from the middleware.</li>
<li>Changed the flow to configure endpoints after configuration change: unconfigure the device or remove all endpoints, add endpoints, configure the device. Updated the functions: <a class="el" href="group__group__usbfs__dev__hal__functions__common.html#ga20cd68fc7ca73e6c333e3c59fd636a22">Cy_USBFS_Dev_Drv_UnConfigureDevice</a>, <a class="el" href="group__group__usbfs__dev__hal__functions__endpoint__config.html#ga81b07ede74c6ad6b99e424afed5fffe7">Cy_USBFS_Dev_Drv_AddEndpoint</a> and <a class="el" href="group__group__usbfs__dev__hal__functions__common.html#gadcd2b88937a1cb573838a3f83655d695">Cy_USBFS_Dev_Drv_ConfigDevice</a>. Removed the Cy_USBFS_Dev_Drv_ConfigDeviceComplete function because it is no needed anymore.</li>
<li>Added the functions: <a class="el" href="group__group__usbfs__dev__hal__functions__ep0__service.html#ga01373022a0ca84da6ad3243a44f0ba85">Cy_USBFS_Dev_Drv_Ep0ReadResult()</a>, <a class="el" href="group__group__usbfs__dev__hal__functions__common.html#gadb382fffcc696975a198f11d1d96c9c2">Cy_USBFS_Dev_Drv_SetAddress()</a> and <a class="el" href="group__group__usbfs__dev__hal__functions__ep0__service.html#ga53e4e574e7fa85fedcc5c20def955428">Cy_USBFS_Dev_Drv_GetEp0MaxPacket()</a>.</li>
<li>Changed the function signature <a class="el" href="group__group__usbfs__dev__hal__functions__ep0__service.html#gae0fe4cc97a8a9a857289bf721ac66c63">Cy_USBFS_Dev_Drv_Ep0Stall()</a>.</li>
<li>Obsolete function Cy_USBFS_Dev_Drv_GetEndpointStallState; the <a class="el" href="group__group__usbfs__dev__hal__functions__data__xfer.html#gaf78e5b3f27c156336655d5e92e90dbc9">Cy_USBFS_Dev_Drv_GetEndpointState()</a> updated to be used instead of the obsolete function.</li>
<li>Reduced the time required to complete abort operation in function <a class="el" href="group__group__usbfs__dev__hal__functions__data__xfer.html#gae4dba7b4e7a47b69f1732d5a216382eb">Cy_USBFS_Dev_Drv_Abort</a>. Obsolete function Cy_USBFS_Dev_Drv_AbortComplete because entire abort operation is handled by <a class="el" href="group__group__usbfs__dev__hal__functions__data__xfer.html#gae4dba7b4e7a47b69f1732d5a216382eb">Cy_USBFS_Dev_Drv_Abort</a>.</li>
<li>Added the endpoint address argument to the <a class="el" href="group__group__usbfs__dev__drv__data__structures.html#ga8f3d05a8716e5d7b1f208038882c8328">cy_cb_usbfs_dev_drv_ep_callback_t</a> to simplify endpoint transfer complete event processing for the MBED-OS USB Device stack.  </li>
</ul>
</td><td>Updated the driver to support the MBED-OS USB Device stack and Cypress USB Device middleware.  </td></tr>
<tr>
<td rowspan="2">1.10 </td><td>Fixed the <a class="el" href="group__group__usbfs__dev__hal__functions__common.html#gab9f5b81775dcb9b664ac8bd46f5b89a8">Cy_USBFS_Dev_Drv_Disable</a> function to not disable DMA in CPU mode. </td><td>Calling this function triggers assert because DMA for endpoints is not initialized/used in the CPU mode.  </td></tr>
<tr>
<td>Updated the condition statement in the <a class="el" href="group__group__usbfs__dev__drv__macros.html#gaef72dcffc85aefe650f79dd21dbdb29c">CY_USBFS_DEV_DRV_ALLOC_ENDPOINT_BUFFER</a> macro to explicitly check against non-zero. </td><td>Fixed MISRA 13.2 violation in the macro.  </td></tr>
<tr>
<td>1.0 </td><td>The initial version. </td><td></td></tr>
</table>
<table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="groups"></a>
API Reference</h2></td></tr>
<tr class="memitem:group__group__usbfs__dev__drv__macros"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__group__usbfs__dev__drv__macros.html">Macros</a></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:group__group__usbfs__dev__drv__functions"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__group__usbfs__dev__drv__functions.html">Functions</a></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:group__group__usbfs__dev__drv__data__structures"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__group__usbfs__dev__drv__data__structures.html">Data Structures</a></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:group__group__usbfs__dev__drv__enums"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__group__usbfs__dev__drv__enums.html">Enumerated Types</a></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table>
</div><!-- contents -->
</div><!-- doc-content -->
<!-- start footer part
<div id="nav-path" class="navpath">
    <ul>
        <li class="footer">
            Generated for <b>MTB CAT1 Peripheral driver library</b> by <b>Cypress Semiconductor Corporation</b>.
            All rights reserved.
        </li>
    </ul>
</div>
-->
</body>
</html>
